package com.hk.service.order.impl;

import com.hk.commons.*;
import com.hk.commons.enm.ConfirmStatusEnum;
import com.hk.commons.enm.PayStatusEnum;
import com.hk.commons.entity.Organization;
import com.hk.commons.entity.order.OrderInfo;
import com.hk.commons.entity.order.OrderInfoHistory;
import com.hk.commons.entity.order.OrderRouteInfo;
import com.hk.commons.entity.order.OrderStatements;
import com.hk.commons.entity.pay.FM;
import com.hk.commons.entity.product.Company;
import com.hk.commons.entity.product.HistoryPayment;
import com.hk.commons.entity.product.Payment;
import com.hk.commons.entity.product.ProductInfo;
import com.hk.commons.entity.sys.SysUser;
import com.hk.commons.utils.order.OrderCreateMsg;
import com.hk.commons.utils.order.OrderInfoHuoChaiMsg;
import com.hk.commons.utils.sys.DataHelper;
import com.hk.commons.utils.yingmi.HuochaiApiUtils;
import com.hk.commons.vo.OrderStrMsg;
import com.hk.commons.vo.UserCardMsg;
import com.hk.dao.base.impl.BaseServiceImpl;
import com.hk.service.IFundInfo_Yimi;
import com.hk.service.IOrganization;
import com.hk.service.IUserChannel;
import com.hk.service.kyc.ICard;
import com.hk.service.kyc.ICoupon;
import com.hk.service.order.*;
import com.hk.service.product.ICompany;
import com.hk.service.product.IProductInfo;
import com.hk.service.sys.IBank;
import com.hk.service.sys.ISysUser;
import com.hk.service.sys.ISysUserRoles;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

@Service
public class HuochaiOrderImpl extends BaseServiceImpl<OrderInfo> implements
		IOrderHandle<OrderInfo> {

	private static final String HC_ORDER_LIST = "HC_ORDER_LIST";

	/**
	 * 检查订单是否超时, 大于120分钟将会认为是超时
	 */
	public static final int ORDER_TIME_OUT = 120 * 60 * 1000;

	private static Logger logger = LoggerFactory.getLogger(HuochaiOrderImpl.class);

	@Autowired
	private IReservation reservationService;

	@Autowired
	private ISysUser userService;

	@Autowired
	private IPayment paymentService;

	@Autowired
	private IHistoryPayment historyPaymentService;

	@Autowired
	private IBank bankService;

	@Autowired
	private IOrderStatements orderStatementsService;

	@Autowired
	private IProductInfo productService;

	@Autowired
	private ICompany comService;

	@Autowired
	private IFundInfo_Yimi fundInfoService;

	@Autowired
	private IOrderInfo orderService;

	@Autowired
	private IOrganization orgService;

	@Autowired
	private ISysUserRoles roleService;


	@Autowired
	private IUserChannel userChannelService;


	@Autowired
	private ICoupon couponService;

	@Autowired
	private ICard cardService;

	@Autowired
	private IOrderCheck orderCheckService;

	@Autowired
	private IOrderInfoHistory orderInfoHistoryService;

	@Value("${huochai.basePath}")
	private String basePath;

	@Value("${huochai.getInfoUrl}")
	private String getInfoUrl;

	@Value("${huochai.buyUrl}")
	private String buyUrl;

	@Value("${huochai.buyCbFunName}")
	private String buyCbFunName;

	@Value("${huochai.duplicateInfo}")
	private String duplicateInfo;

	@Value("${qingniu.pdf}")
	private String QN_PDF;

	@Autowired
	private IOrderRouteInfo orderRouteService;

	// 支付状态未确认
	public static final int HC_PAY_NO_CONFIRM = 0;

	// 支付成功
	public static final int HC_PAY_SUCC = 2;

	// 支付失败
	public static final int HC_PAY_FAIL = 1;

	/**
	 * 查询redis中所有的订单
	 */
	public void checkAllOrderInRedis() {

		List<OrderInfo> orderList = getOrderListFromRedis();

		if (orderList != null && orderList.size() > 0) {
			for (OrderInfo orderInfo : orderList) {
				this.updInfoTask(orderInfo.getUserId(), orderInfo.getId());
			}
		}
	}

	/**
	 * 根据传入信息 创建火柴订单
	 *
	 * orderInfo: 用于在数据库中保存订单信息 OrderInfoHuoChaiMsg hcOrderInfo 用来封装app 前端返回的信息
	 *
	 *
	 * @param productId
	 * @param userId
	 * @return
	 */
	@Override
	public OrderCreateMsg create(Long productId, Long userId, Long userCardId) {
		logger.info("OrderCreateMsg create hc order-- userId = " + userId
				+ " productId = " + productId + "  userCardId = " + userCardId);

		// 01 如果用户使用加息券，则替换原有产品id
		String productIdStr = String.valueOf(productId);
		Long newProductId = null;
		ProductInfo productInfo = this.productService.findById(productId);
		boolean isUseUserCard = false;

		if(userCardId != null){
			UserCardMsg userCardMsg = couponService.getCouponInfo(userId, userCardId);
			if(userCardMsg != null){
				BigDecimal addRate = userCardMsg.getFaceValue();
				BigDecimal rate01 = new BigDecimal(0.005).setScale(3, BigDecimal.ROUND_HALF_DOWN);
				BigDecimal rate02 = new BigDecimal(0.002).setScale(3, BigDecimal.ROUND_HALF_DOWN);
				if (productInfo != null) {
					if (productInfo.addRateProduct01 != null) {
						ProductInfo rateProduct = this.productService.findById(productInfo.addRateProduct01);
						if (rateProduct != null) {
							if (addRate.setScale(3, BigDecimal.ROUND_HALF_DOWN).equals(rate01)) {
								isUseUserCard = true;
								newProductId = this.getNewProductId(productId, addRate);
							}
						}
					}
					if (productInfo.addRateProduct02 != null) {
						ProductInfo rateProduct = this.productService.findById(productInfo.addRateProduct02);
						if (rateProduct != null) {
							if (addRate.setScale(3, BigDecimal.ROUND_HALF_DOWN).equals(rate02)) {
								isUseUserCard = true;
								newProductId = this.getNewProductId(productId, addRate);
							}
						}
					}
				}

			}
		}

		/*
		UserCard userCard = null;
		if (userCardId != null) {
			userCard = userCardService.findById(userCardId);
			if (userCard != null) {
				Card card = cardService.findById(userCard.getCardId());
				if (card != null) {
					BigDecimal addRate = card.getRate();
					newProductId = this.getNewProductId(productId, addRate);
				}

			}
		}

		*/
		// 替换产品Id
		if (newProductId != null) {
			productId = newProductId;
		}

		OrderCreateMsg huoChaiRes = new OrderCreateMsg();

		// 02 参数检测判断参数是否异常, 如果参数异常则直接返回
		logger.info("OrderCreateMsg 01 check parms");
		if (productId == null || productInfo == null
				|| userService.existById(userId) == false) {
			logger.info("create hc order-- data check failed! productId = "
					+ productId + "  userId = " + userId);
			huoChaiRes.setErrorCode(ConstantOrderStatus.CREATE_ORDER_ERROR_01);
			return huoChaiRes;
		}

		// 03创建订单
		OrderInfo orderInfo = createOrderInfo(userCardId, productId, userId);
		logger.info("**********hc 订单初始化之后的信息为 ************** " + orderInfo.toString());

		Long orderId = orderInfo.getId();
		logger.info("OrderCreateMsg 02 create orderInfo, orderId = " + orderId);

		RedisCilent.setString(
				ConstantsOrder.ORDER_HC_PRIX + String.valueOf(orderId),
				productIdStr, 172800);
		String msg = getAppReturnMsg(orderInfo);
		huoChaiRes.setUrl(basePath + buyUrl);
		huoChaiRes.setInfo(msg);
		huoChaiRes.setOrderId(orderInfo.getId());
		huoChaiRes.setErrorCode(ConstantOrderStatus.CREATE_ORDER_NO_ERROR);
		huoChaiRes.setOrderId(orderId);
		huoChaiRes.setCompanyId(ConstantRoute.COMPANY_HUOCHAI);
		huoChaiRes.setUserId(userId);

		logger.info("OrderCreateMsg 02 create app return message. response message orderId = "
				+ orderId + " userId = " + userId + " info = " + msg);

		OrderInfoHistory orderInfoHistory = new OrderInfoHistory(orderInfo);
		this.orderInfoHistoryService.add(orderInfoHistory);

		// 04 更改加息券的状态为已使用
		if(isUseUserCard == true){
			couponService.activeCoupon(userCardId, userId, orderId, true);
		}
		/*

		if (userCard != null) {
			logger.info("加息券不为空，将更改加息券的使用状态");
			userCard.setStatus(ConstantCard.CARD_STATUS_ACTIVE);
			userCard.setOrderId(orderId);
			userCard.setUseTime(System.currentTimeMillis());

			userCardService.update(userCard);
			logger.info("将加息券id的状态修改为已使用 userCardId = " + userCard.getId()
					+ " orderId = " + orderId);
		}
		*/
		return huoChaiRes;

	}

	/**
	 * 根据 productId 和 userId 获取订单信息
	 *
	 * @param productId
	 * @param userId
	 * @return
	 */
	private OrderInfo createOrderInfo(Long userCardId, Long productId, Long userId) {
		logger.info("createOrderInfo create orderInfo productId = " + productId
				+ "  userId = " + userId);

		SysUser user = userService.findById(userId);

		if (user == null) {
			return null;
		}
		// 创建订单，用于保存在数据库
		OrderInfo orderInfo = new OrderInfo();
		orderInfo.setProductId(productId);
		orderInfo.setUserId(userId);

		Long orderId = LongIdThreadSafety.get();
		orderInfo.setId(orderId);
		orderInfo.setUserCardId(userCardId);
		orderInfo.setCompanyId(ConstantRoute.COMPANY_HUOCHAI);
		orderInfo.setBrokerOrderNo("hc" + orderId.toString());
		orderInfo.setPayStatus(ConstantOrderStatus.PAY_STATUS_ERR);
		orderInfo
				.setConfirmStatus(ConstantOrderStatus.CONFIRM_STATUS__NO_CONFIRM);
		orderInfo.setOrderCreatedOn(System.currentTimeMillis());

		/*
		 * 加息收益 private BigDecimal extraDividend; private BigDecimal
		 * prodDividend; private Long userCardId;
		 */
		// 添加支付信息
		Payment pay = paymentService.getByUserId(userId);
		if (pay != null) {
			orderInfo.setPaymentId(pay.getId());
		}

		// 订单的渠道跟用户的渠道一致
		if (user.getChannel() != null) {
			orderInfo.setChannel(user.getChannel());
		} else {
			orderInfo.setChannel(ConstantUserChannel.USER_CHANNEL_WUZHU);
		}

		if (userService.getFinUserIdByUserId(userId) != null) {
			Long finUserId = userService.getFinUserIdByUserId(userId);

			SysUser financialUser = userService.findById(finUserId);

			if(financialUser != null && financialUser.getIsInside() == 1){
				orderInfo.setFinancialPlannerId(finUserId);
			}
//			if (financialUser != null) {
//				if (financialUser.getOrgId() != null) {
//					int orgId = financialUser.getOrgId();
//					// 给订单添加组织架构id
//					orderInfo.setOrgId(orgId);
//					// 给订单添加渠道id
//					orderInfo.setChannel(orgService.getChannelById(orgId));
//				}
//			}
		}

		if(user.getOrgId() != null){
			orderInfo.setOrgId(user.getOrgId());
		}

		if(user.getChannel() != null){
			orderInfo.setChannel(user.getChannel());
		}



		// 将记录保存在缓存中
		addOrderIntoRedis(orderInfo);
		return orderInfo;
	}

	/**
	 * 封装app 返回的结果信息
	 *
	 * @param orderInfo
	 * @return
	 */
	private String getAppReturnMsg(OrderInfo orderInfo) {

		Long userId = orderInfo.getUserId();
		SysUser user = userService.findById(userId);
		Long orderId = orderInfo.getId();

		Long productId = orderInfo.getProductId();
		ProductInfo productInfo = productService.findById(productId);

		// 创建火柴订单，hcOrderInfo 用于封装信息给app前端
		OrderInfoHuoChaiMsg hcOrderInfo = new OrderInfoHuoChaiMsg();
		hcOrderInfo.setOrderId(orderId);
		hcOrderInfo.setProductId(productInfo.getId());
		hcOrderInfo.setUserId(orderInfo.getUserId());
		hcOrderInfo.setProductCode(productInfo.getProNo());
		hcOrderInfo.setPhoneNum(user.getName());

		if (orderInfo.getPaymentId() != null) {
			Payment payment = paymentService.findById(orderInfo.getPaymentId());
			if (payment != null) {
				hcOrderInfo.setUserName(payment.getAccountName());
				hcOrderInfo.setIdentity(payment.getIdentityNo());
				hcOrderInfo.setPaymentNo(payment.getPaymentNo());
			}
		}

		// 封装数据
		hcOrderInfo.setCbFunName(buyCbFunName + "?id=" + productId + "&userid=" + userId + "&buyChannel=2&version=1.51&time=" + System.currentTimeMillis());
		String infoStr = JsonUtils.toJson(hcOrderInfo);
		logger.info("hc buy " + "userId = " + userId + " info = " + infoStr);
		// 将数据进行加密
		String encryptMSG = AES.encrypt(infoStr);

		return encryptMSG;
	}

	/**
	 * 判断是否要从redis中删除订单信息，并退还加息券
	 *
	 * @param userId
	 * @param orderId
	 * @return
	 */
	public Boolean deleteOrderTask(Long userId, Long orderId) {


		OrderInfo order = getOrderFromRedis(orderId);

		// 如果订单不存在，则返回
		if (order == null || order.getId() == null) {
			return true;
		}

		Long userCardId = order.getUserCardId();

		// 检查订单是否超时, 大于120分钟将会认为是超时
		if (System.currentTimeMillis() - order.getOrderCreatedOn() > ORDER_TIME_OUT) {

			deleteOrderFromRedis(orderId);

			logger.info(" orderCreate on " + DateUtil.longToLongDate(order.getOrderCreatedOn()) + "  will delete from redis");

			// 从缓存中删除userCard 相关的信息
			logger.info(" 火柴订单未支付，更改火柴订单的加息券为未使用  orderId ={}", orderId);

			//给用户退还卡券
			if(userCardId != null) {
				couponService.activeCoupon(userCardId, userId, null, false);
			}

		}

		return true;
	}
	/**
	 * 根据userId 和orderId 更新火柴的订单
	 *
	 * @param userId
	 * @param orderId
	 * @return
	 */
	public Boolean updInfoTask(Long userId, Long orderId) {
		Boolean continueFlag = true;
		//logger.info("updInfoTask in userId = " + userId + "  orderId = " + orderId);
		// 获得请求连接
		String updUrl = basePath + getInfoUrl;

		// 获取返回结果
		String result = HuochaiApiUtils.doPost(updUrl, orderId);

		OrderInfo order = getOrderFromRedis(orderId);
		// 如果订单不存在，则返回
		if (order == null || order.getId() == null) {
			return true;
		}

		Long userCardId = order.getUserCardId();

		// 检查订单是否超时, 大于120分钟将会认为是超时
		if (System.currentTimeMillis() - order.getOrderCreatedOn() > ORDER_TIME_OUT) {

			deleteOrderFromRedis(orderId);

			logger.info(" orderCreate on " + DateUtil.longToLongDate(order.getOrderCreatedOn()) + "  will delete from redis");

			// 从缓存中删除userCard 相关的信息
			logger.info(" 火柴订单未支付，更改火柴订单的加息券为未使用  orderId ={}", orderId);

			//给用户退还卡券
			couponService.activeCoupon(userCardId, userId, null, false);

			return true;
		}

		// 如果从火柴的返回数据中可以得到订单信息
		if (checkOrderExistInHC(result)) {
			continueFlag = updRecord(userId, orderId, result);
			//logger.info("*******updInfoTask continueFlag = " + continueFlag);
		}

		//停止检查更新时退还加息券
		if(userCardId != null && continueFlag == false){
			OrderInfo existOrder = orderService.findById(orderId);
			if(existOrder == null){
				couponService.activeCoupon(userCardId, userId, null, false);
				logger.info("*******火柴订单支付失败，将会退还加息券************** orderId ={}, userCardId={}", orderId, userCardId);
			}
		}

		return continueFlag;
	}

	/**
	 * 根据火柴返回的 信息判断订单是否存在
	 */
	private Boolean checkOrderExistInHC(String str) {

		//logger.info(" checkOrderExistInHC Huochai response message is  msg = "		+ str);

		Boolean result = false;
		if (StringHelper.isNotEmpty(str)) {
			org.codehaus.jackson.JsonNode resultNode = null;

			resultNode = JsonUtils.toJsonObject(str);
			Integer resultCode = 0;
			// 获得返回结果码
			if (resultNode.get("resultCode") != null) {
				resultCode = resultNode.get("resultCode").asInt();
			}

			//logger.info("checkOrderExistInHC resultCode = " + resultCode);
			// 如果成功返回,则获取订单的相关属性，并判断是否更新订单
			if (resultCode == ConstantRoute.CB_SUCCESS_CODE) {
				result = true;
			}

		} else {
			//logger.info("checkOrderExistInHC msg is null");
		}
		return result;
	}

	/**
	 * 根据火柴返回的信息更新订单信息
	 *
	 * @param orderId
	 * @param respStr
	 * @return
	 */
	private Boolean updRecord(Long userId, Long orderId, String respStr) {
		Boolean continueCheckFlage = true;
		String key = ConstantsOrder.ORDER_HC_PRIX + String.valueOf(orderId);
		if ( !(RedisCilent.existsKey(key))){
			logger.info("order is not in the redis and will stop update");
			return false;
		}

		// 查询订单信息
		org.codehaus.jackson.JsonNode result = null;

		logger.info(" Huochai response message is orderId = "
				+ orderId.toString() + " msg = " + respStr);

		result = JsonUtils.toJsonObject(respStr);

		Integer resultCode = 0;

		// 获得返回结果码, 如果没有结果码则退出, 继续查询
		if (result.get("resultCode") != null) {
			resultCode = result.get("resultCode").asInt();
		} else {
			continueCheckFlage = true;
			return continueCheckFlage;
		}

		// 订单的利息
		BigDecimal dividend = null;
		String dividendStr = result.get("dividend").asText();
		if (StringHelper.isNotEmpty(dividendStr)
				&& (!dividendStr.equals("null"))) {
			dividend = new BigDecimal(dividendStr);
		}

		// 用户输入的金额
		BigDecimal amount = null;
		String amountStr = result.get("amount").toString();
		if (StringHelper.isNotEmpty(amountStr) && (!amountStr.equals("null"))) {
			amount = new BigDecimal(amountStr);
		}
		String userName = result.get("userName").asText();
		String identity = result.get("identity").asText();
		String paymentNo = result.get("paymentNo").asText();
		Integer payStatus = result.get("payStatus").asInt();
		String phoneNum = result.get("phoneNum").asText();
		Long orderTradeDate = result.get("orderTradeDate").asLong();
		Long dividendDate = result.get("dividendDate").asLong();

		// 如果成功返回,则获取订单的相关属性,如果支付成功，则添加订单记录
		if (resultCode == ConstantRoute.CB_SUCCESS_CODE) {
			// 检查是否支付成功，如果支付成功则更新
			if (payStatus == HC_PAY_SUCC) {
				logger.info("payStatus == true  userId = " + userId
						+ "  paymentNo = " + paymentNo + "  identity = "
						+ identity + " userName = " + userName
						+ "  phoneNum = " + phoneNum + "  orderId = " + orderId);

				// 01 添加订单的支付状态
				Long paymentId = addNewPayment(userId, paymentNo, identity,
						userName, phoneNum);

				// 02创建订单并保存
				OrderInfo orderInfo = getOrderFromRedis(orderId);

				Long userCardId = orderInfo.getUserCardId();

				orderInfo.setDividendDate(dividendDate);
				orderInfo.setPayStatus(payStatus);
				orderInfo
						.setConfirmStatus(ConstantOrderStatus.CONFIRM_STATUS__TRUE);
				orderInfo.setDividend(dividend);
				orderInfo.setPaymentId(paymentId);
				orderInfo.setOrderTradeDate(orderTradeDate);
				orderInfo.setOrderConfirmDate(System.currentTimeMillis());
				orderInfo.setSuccessAmount(amount);
				orderInfo.setCompanyId(ConstantRoute.COMPANY_HUOCHAI);

				/*
				if (RedisCilent.existsKey(ConstantsOrder.ORDER_HC_PRIX
						+ String.valueOf(orderInfo.getId()))) {
					String oldProductId = RedisCilent
							.getString(ConstantsOrder.ORDER_HC_PRIX
									+ String.valueOf(orderInfo.getId()));
					logger.info("即将更新产品募集额度oldProductId={}", oldProductId);
					// 04 更新产品信息，增加已募集金额，减少剩余额度
					productService.updAmountByPay(Long.valueOf(oldProductId),
							amount, true);
				} else {
					logger.info("该火柴订单没有保存到缓存中！！orderId={}", orderInfo.getId());
					return false;

					productService.updAmountByPay(orderInfo.getProductId(),
							amount, true);

				}
				*/

				couponService.activeCoupon(userCardId, userId, orderId, true);

				ProductInfo productInfo = productService.findById(orderInfo
						.getProductId());
				int term = productInfo.getProTerm();


				//产品原有收益、产品原有收益率
				BigDecimal prodRate = DataHelper.chgPrecentToBigDecimal(productInfo.getMaxYearRate());
				orderInfo.setProRate(prodRate);
				orderInfo.setProdDividend(DataHelper.getDividend(prodRate, term, amount));

				//设置额外收益率为0
				BigDecimal extRate =  BigDecimal.valueOf(0.00);
				BigDecimal extDividend =  BigDecimal.valueOf(0.00);

				if(userCardId != null && couponService.getCouponInfo(userId, userCardId) != null){
					UserCardMsg userCardMsg = couponService.getCouponInfo(userId, userCardId);

					//设置订单的优惠类型
					orderInfo.setBenefitType(userCardMsg.getCardType());

					orderInfo.setUserCardId(userCardId);
					extDividend =  DataHelper.getDividend(userCardMsg.getFaceValue(), term, amount);
					orderInfo.setExtraDividend(extDividend);
					extRate = userCardMsg.getFaceValue();
					orderInfo.setExtRate(extRate);
					orderInfo.setUserCardRate(extRate);
					orderInfo.setUserCardDividend(extDividend);

					//如果使用的加息券，则更改产品的利息和原有收益
					BigDecimal rate =  prodRate.subtract(extRate);
					orderInfo.setProRate(rate);
					orderInfo.setProdDividend(DataHelper.getDividend(rate, term, amount));
				}

				//设置产品的总收益率
				orderInfo.setTotalRate(prodRate);
				orderInfo.setRealPayAmt(amount);
				orderInfo.setPayBackAmt(amount.add(dividend));

				/*
				UserCard userCard = userCardService.updateStatus(userCardId, orderId, true);
				if (userCard != null) {
					orderInfo.setUserCardId(userCard.getId());
					int cardId = userCard.getCardId();
					ProductInfo productInfo = productService.findById(orderInfo
							.getProductId());
					int days = productInfo.getProTerm();
					extraProfit = getExtraProfit(cardId, amount, days);
					orderInfo.setExtraDividend(extraProfit);
				}
				*/


				//设置真实付款金额
				orderInfo.setRealPayAmt(amount);

				//设置还款金额
				orderInfo.setPayBackAmt(amount.add(dividend));

				// 添加订单记录
				logger.info("********************hc 即将把订单写入orderInfo 表中 start ***********************");
				logger.info("orderInfo = " + orderInfo.toString());
				orderService.add(orderInfo);
				logger.info("********************hc 即将把订单写入orderInfo 表中 end ***********************");
				orderRouteService.addByOrder(orderInfo);


				//更改产品的已募集额度
				productService.updAmountByPay(orderInfo.getProductId(), orderInfo.getSuccessAmount(), true);


				// 添加订单流水信息
				logger.info("will insert order into the orderStatements");
				OrderStatements orderStatements = new OrderStatements();
				ReqToModelHelper
						.copyReqValueToModel(orderInfo, orderStatements);
				orderStatementsService.add(orderStatements);

				/*
				// 添加订单路由信息
				logger.info("will insert order into the orderRoute");
				createOrderRoute(userId, orderId, orderInfo.getProductId(),
						orderInfo.getCompanyId());
				*/
			}
		}

		logger.info("payStatus = " + payStatus + " orderId = " + orderId);
		// 不需要继续查询
		if (payStatus == HC_PAY_SUCC || payStatus == HC_PAY_FAIL) {
			continueCheckFlage = false;
		}

		// 如果结果已经确定，则不需要再次查询
		if (continueCheckFlage == false) {
			stopCheck(userId, orderId);
		}

		return continueCheckFlage;

	}


	/**
	 * 将支付信息保存在支付记录表中
	 *
	 * @param userId
	 *            用户id
	 * @param paymentNo
	 *            银行卡号
	 * @param identity
	 *            身份证号
	 * @param userName
	 *            用户姓名
	 * @param phoneNum
	 *            银行卡关联的手机号
	 */
	public Long addNewPayment(Long userId, String paymentNo, String identity,
			String userName, String phoneNum) {
		Long paymentId = null;
		logger.info("updatePaymentInfo userId = " + userId + "  paymentNo = "
				+ paymentNo + "  identity = " + identity + " userName = "
				+ userName + "  phoneNum = " + phoneNum);

		// 更新用户的相关信息
		userService.upUserByPayment(userId, null, identity, userName);

		// 判断用户身份信息和卡片信息是否一致

		SysUser user = userService.findById(userId);

		if (identity != null && user.getIdentity() != null
				&& (!user.getIdentity().equalsIgnoreCase(identity))) {
			logger.info("身份证号码不一致  identityNo in DB  = " + user.getIdentity()
					+ " identityNo in payment = " + identity);
			return null;
		}

		// /**
		// * add by Sam 2016/06/22 Start-------------------------------
		// * 验证用户输入的手机号与登录者的帐号是否一致， 考虑到 支付安全性，平台策略验证用户输入的四要素，拿手机号码
		// * 与平台用户登录后的Name进行一致性匹配。 End---------------------------------
		// */
		// if (!user.getName().equals(phoneNum)) {
		// logger.info("该用户手机号码不一致  name = " + user.getName() + " phoneNum = "
		// + phoneNum);
		// return null;
		// }

		HqlFilter hqlFilter = new HqlFilter();
		// hqlFilter.addEQFilter("userId", userId);
		hqlFilter.addEQFilter("paymentNo", paymentNo);
		List<Payment> existPaymentList = paymentService.findByFilter(hqlFilter);
		String bankName=null;
		if (existPaymentList.size() > 0) {
			Payment existPayment = existPaymentList.get(0);
			if (StringHelper.isEmpty(existPayment.getAccountName())
					|| StringHelper.isEmpty(existPayment.getIdentityNo())
					|| StringHelper.isEmpty(existPayment.getPhone())) {
				existPayment.setAccountName(userName);
				existPayment.setPhone(phoneNum);
				existPayment.setIdentityNo(identity);
				paymentService.update(existPayment);
			}
			String huochaiCompany = paymentService.getCardCompany(
					ConstantRoute.COMPANY_HUOCHAI, existPayment);
			if ((ConstantRoute.COMPANY_HUOCHAI + "").equals(huochaiCompany)) {
				logger.info("该用户已在火柴绑该张卡，不能再次绑卡！userId={}", user.getId());
			} else {// 更新用户绑卡信息
				existPayment.setCardStatus(CardStatusCode.PAYMENT_DISPLAY_SHOW);
				existPayment.setCts(System.currentTimeMillis());
				existPayment.setPhone(phoneNum);
				paymentService.setAddCardCompany(ConstantRoute.COMPANY_HUOCHAI,
						existPayment);
				paymentService.update(existPayment);
				try {
					user.setTieCard(CardStatusCode.PAYMENT_DISPLAY_SHOW);
					userService.update(user);
				} catch (Exception e) {
					logger.error("更新用户表异常！", e);
				}
			}
			paymentId = existPayment.getId();
			bankName=existPayment.getBankName();
		} else {
			Payment newPayment = new Payment();
			newPayment.setPaymentNo(paymentNo);
			newPayment.setIdentityNo(identity);
			newPayment.setAccountName(userName);
			newPayment.setPaymentNo(paymentNo);
			newPayment.setPhone(phoneNum);
			newPayment.setUserRegistPhone(user.getName());
			newPayment.setUserId(userId);
			newPayment.setCts(System.currentTimeMillis());
			newPayment.setCardStatus(CardStatusCode.PAYMENT_DISPLAY_SHOW);
			newPayment.setSupportCompany(CardStatusCode.NEVER_BIND_CARD + ","
					+ ConstantRoute.COMPANY_HUOCHAI + ","
					+ CardStatusCode.NEVER_BIND_CARD);
			// 补全银行卡开户行等信息
			FM fm = GetBankInfoUtil.getBankCardInfo(newPayment.getPaymentNo());
			if (fm != null) {
				if (StringHelper.isNotEmpty(fm.getCnm())) {
					newPayment.setCardType(fm.getCtp());// 卡类型
					newPayment.setBankName(fm.getCnm());// 银行名称
					newPayment.setInsCard(fm.getInscd());// 银行机构号
				}
			}
			paymentId = paymentService.add(newPayment);
			bankName=newPayment.getBankName();
			try {
				user.setTieCard(CardStatusCode.PAYMENT_DISPLAY_SHOW);
				userService.update(user);
			} catch (Exception e) {
				logger.error("更新用户表异常！", e);
			}
		}
		try {
			HistoryPayment historyPayment=new HistoryPayment();
			historyPayment.setCompany(ConstantRoute.COMPANY_HUOCHAI);
			historyPayment.setPaymentType(CardStatusCode.PAYMENT_TYPE_ADD);
			historyPayment.setNewBankNo(paymentNo);
			historyPayment.setUserId(userId);
			historyPayment.setPaymentId(paymentId);
			historyPayment.setNewBankName(bankName);
			historyPaymentService.add(historyPayment);
		} catch (Exception e) {
			logger.error("<--------------------------ERROR------------------------->");
			logger.error("火柴绑卡添加到绑卡历史表中异常!!",e);
		}
		return paymentId;
	}

	@Override
	public Long createOrderRoute(Long userId, Long orderId, Integer companyId) {
		return null;
	}

	public Long createOrderRoute(Long userId, Long orderId, Long productId,
			Integer companyId) {

		OrderRouteInfo orderRouteInfo = new OrderRouteInfo();
		orderRouteInfo.setUserId(userId);
		SysUser user = userService.findById(userId);

		if (user != null) {
			orderRouteInfo.setAccountId(user.getAccountId());

			// 添加理财师id
			if (StringHelper.isNotEmpty(user.getRecommendCode())) {
				SysUser finUser = userService.getByPhoneNum(user
						.getRecommendCode());
				if (finUser != null) {
					orderRouteInfo.setFinancialPlannerId(finUser.getId());
				}
			}

			// 添加accountId
			if (StringHelper.isNotEmpty(user.getAccountId())) {
				orderRouteInfo.setAccountId(user.getAccountId());
			}
		}

		orderRouteInfo.setBrokerOrderNo("hc" + orderId);
		orderRouteInfo.setCompanyId(companyId);
		orderRouteInfo.setProductId(productId);
		orderRouteInfo.setOrderId(orderId);
		Long routeInfoId = orderRouteService.add(orderRouteInfo);

		return routeInfoId;
	}

	@Override
	public List<OrderStrMsg> getAllExceptionOrder() {

		List<OrderInfo> exceptionOrderList = new ArrayList<OrderInfo>();
		exceptionOrderList = getOrderListFromRedis();

		List<OrderStrMsg> orderExcStrList = new ArrayList<OrderStrMsg>();

		if (exceptionOrderList != null && exceptionOrderList.size() > 0) {

			for (OrderInfo orderInfo : exceptionOrderList) {
				OrderStrMsg orderStrMsg = new OrderStrMsg();

				orderStrMsg.setId(orderInfo.getId().toString());
				orderStrMsg.setUserId(orderInfo.getUserId().toString());
				orderStrMsg.setProductId(orderInfo.getProductId().toString());
				if (orderInfo.getPayStatus() != null) {
					orderStrMsg.setPayStatus(orderInfo.getPayStatus()
							.toString());
					orderStrMsg.setPayStatusStr(PayStatusEnum
							.getPayStatus(orderInfo.getPayStatus()));
				}

				if (orderInfo.getOrderCreatedOn() != null) {
					orderStrMsg.setOrderCreatedOn(orderInfo.getOrderCreatedOn()
							.toString());
					orderStrMsg.setOrderCreatedOnStr(DateUtil
							.longToLongDate(orderInfo.getOrderCreatedOn()));
				}
				orderStrMsg.setPaymentId("" + orderInfo.getPaymentId());
				// 封装订单信息，并保存在orderStrMsg中
				orderStrMsg = updOrderStrMsg(orderStrMsg);

				orderExcStrList.add(orderStrMsg);
			}

		}
		return orderExcStrList;
	}

	@Override
	public OrderStrMsg getStrInfoById(Long userId, Long orderId) {

		OrderStrMsg orderStrMsg = new OrderStrMsg();
		OrderInfo orderInfo = orderService.findById(orderId);

		// 如果订单为空，或者支付信息不为成功或回款，则返回空
		if (orderInfo == null
				|| (orderInfo.getPayStatus() != ConstantOrderStatus.PAY_STATUS_TRUE && orderInfo
						.getPayStatus() != ConstantOrderStatus.PAY_STATUS_PAYBACK)) {
			return null;
		}

		orderStrMsg = new OrderStrMsg();

		// 01加入订单基本属性
		orderStrMsg.setId(orderInfo.getId().toString());
		orderStrMsg.setUserId(orderInfo.getUserId().toString());
		orderStrMsg.setProductId(orderInfo.getProductId().toString());
		if (orderInfo.getPaymentId() != null) {
			orderStrMsg.setPaymentId(orderInfo.getPaymentId().toString());
		}

		if (orderInfo.getSuccessAmount() != null) {
			orderStrMsg.setAmount(orderInfo.getSuccessAmount()
					.toEngineeringString());
		} else {
			orderStrMsg.setAmount("");
		}

		// 理财师信息
		if (orderInfo.getFinancialPlannerId() != null) {
			orderStrMsg.setFinancialPlannerId(orderInfo.getFinancialPlannerId()
					.toString());
		}

		if (orderInfo.getPayStatus() != null) {
			orderStrMsg.setPayStatus(orderInfo.getPayStatus().toString());
			orderStrMsg.setPayStatusStr(PayStatusEnum.getPayStatus(orderInfo
					.getPayStatus()));
		}

		if (orderInfo.getConfirmStatus() != null) {
			orderStrMsg.setConfirmStatus(orderInfo.getConfirmStatus()
					.toString());
			orderStrMsg.setConfirmStatusStr(ConfirmStatusEnum
					.getConfirmStatus(orderInfo.getConfirmStatus()));
		}

		if (orderInfo.getOrderCreatedOn() != null) {
			orderStrMsg.setOrderCreatedOn(orderInfo.getOrderCreatedOn()
					.toString());
			orderStrMsg.setOrderCreatedOnStr(DateUtil.longToLongDate(orderInfo
					.getOrderCreatedOn()));
		}

		if (orderInfo.getOrderConfirmDate() != null) {
			orderStrMsg.setOrderConfirmDate(orderInfo.getOrderConfirmDate()
					.toString());
			orderStrMsg.setOrderConfirmDateStr(DateUtil
					.longToShortDate(orderInfo.getOrderConfirmDate()));
		}

		if (orderInfo.getOrderTradeDate() != null) {
			orderStrMsg.setOrderTradeDate(orderInfo.getOrderTradeDate()
					.toString());
			orderStrMsg.setOrderTradeDateStr(DateUtil.longToShortDate(orderInfo
					.getOrderTradeDate()));
		}

		if (orderInfo.getDividendDate() != null) {
			orderStrMsg.setOrderDividendDate(orderInfo.getDividendDate()
					.toString());
			orderStrMsg.setOrderDividendDateStr(DateUtil
					.longToShortDate(orderInfo.getDividendDate()));
		}



		if (orderInfo.getUserCardId() != null) {
			orderStrMsg
					.setUserCardId(String.valueOf(orderInfo.getUserCardId()));
		}


		if(orderInfo.getRealPayAmt() != null){
			orderStrMsg.setRealPayAmt(orderInfo.getRealPayAmt().setScale(2, BigDecimal.ROUND_HALF_UP).toString());
		}

		if(orderInfo.getPayBackAmt() != null){
			BigDecimal payBackAmt  =  orderInfo.getPayBackAmt().setScale(2, BigDecimal.ROUND_HALF_UP);
			orderStrMsg.setPayBackAmt( payBackAmt.toString());
		}


		if (orderInfo.getDividend() != null) {
			orderStrMsg.setDividend(orderInfo.getDividend().setScale(2, BigDecimal.ROUND_HALF_UP).toString());
		}

		if (orderInfo.getExtraDividend() != null) {
			orderStrMsg.setExtraDivendend(String.valueOf(orderInfo.getExtraDividend().setScale(2, BigDecimal.ROUND_HALF_UP)).toString());
		}

		if (orderInfo.getProdDividend() != null) {
			orderStrMsg.setProdDivendend(String.valueOf(orderInfo
					.getProdDividend().setScale(2, BigDecimal.ROUND_HALF_UP)).toString());
		}

		//合同标题
		if(StringHelper.isNotEmpty(orderInfo.getContractTitle())){
			orderStrMsg.setContractTitle( orderInfo.getContractTitle());
		}

		//合同url
		if(StringHelper.isNotEmpty(orderInfo.getContractUrl())){
			orderStrMsg.setContractUrl(QN_PDF + orderInfo.getContractUrl());
			orderStrMsg.setContractUrlHTML(QN_PDF+orderInfo.getContractUrlHTML());
		}

		orderStrMsg.setBenefitType(orderInfo.getBenefitType());

		// 给定单添加组织架构，并且增加组织架构描述
		if (orderInfo.getOrgId() != null) {
			orderStrMsg.setOrgId(String.valueOf(orderInfo.getOrgId()));
			Organization org = orgService.findById(orderInfo.getOrgId());
			if (org != null) {
				orderStrMsg.setOrgName(org.getFlag02());
			}
		}

		// 设置渠道描述
		if (orderInfo.getChannel() != null) {
			Integer channelId = orderInfo.getChannel();
			String channelName = userChannelService.getChannelNameByChannelId( channelId);
			orderStrMsg.setChannelName(channelName);
			orderStrMsg.setChannel(channelId.toString());
		}

		// 封装订单信息，并保存在orderStrMsg中
		orderStrMsg = updOrderStrMsg(orderStrMsg);

		return orderStrMsg;
	}

	private void stopCheck(Long userId, Long orderId) {
		deleteOrderFromRedis(orderId);
	}

	@Override
	public OrderInfo findById(long id) {
		return getById(id);
	}

	/**
	 * 从redis 中读取订单列表
	 *
	 * @return
	 */

	private static List<OrderInfo> getOrderListFromRedis() {
		logger.info("checkLog in start getOrderListFromRedis}");
		List<OrderInfo> orderList = null;

		// 从缓存中获取订单信息
		if (RedisCilent.existsKey(HC_ORDER_LIST)) {
			orderList = RedisCilent.listGet(HC_ORDER_LIST,  0, 500)
					.parallelStream()
					.map(orderStrInfo -> JsonUtils.toBean(orderStrInfo, OrderInfo.class))
					.collect(Collectors.toList());
			logger.info("huochai order in redis  size={}", orderList.size());
		}else{
			logger.info("huochai order in redis is null");
		}

		logger.info("checkLog in end  getOrderListFromRedis}");
		return orderList;
	}




	public static OrderInfo getOrderFromRedis(Long orderId) {
		logger.info("checkLog in start getOrderFromRedis orderId ={}", orderId);
		List<OrderInfo> orderList = getOrderListFromRedis();

		List<OrderInfo> orderAfterFilterList  = orderList.parallelStream()
				.filter(orderInfo->orderInfo != null && orderInfo.getId() != null && orderInfo.getId().equals(orderId))
				.collect(Collectors.toList());

		OrderInfo order = null;
		if(orderAfterFilterList != null && orderAfterFilterList.size() >= 1){
			 order = orderAfterFilterList.get(0);

		}

		logger.info("checkLog in end getOrderFromRedis orderId ={}", orderId);

		return order;
	}

	/**
	 * 将订单存入redis中
	 * 
	 * @param orderInfo
	 * @return
	 */

	public List<OrderInfo> addOrderIntoRedis(OrderInfo orderInfo) {
		logger.info("in addOrderIntoRedis orderId ={}", orderInfo.getId());

		RedisCilent.listSet(HC_ORDER_LIST, JsonUtils.toJson(orderInfo));


		return getOrderListFromRedis();

	}

	/**
	 * 将订单从redis中移除
	 * 
	 * @param orderId
	 * @return
	 */
	public void deleteOrderFromRedis(Long orderId) {

		logger.info("deleteOrderFromRedis will delete order from redis  orderID = " + orderId );
		// 从缓存中获取订单信息
		if (RedisCilent.existsKey(HC_ORDER_LIST)) {

			// 从缓存中获取订单信息
			String strMsg = RedisCilent.listGet(HC_ORDER_LIST,  0, 500)
						.parallelStream()
						.filter(orderStrMsg -> orderStrMsg.indexOf(orderId.toString()) >= 0)
						.collect(Collectors.toList())
						.get(0);

			logger.info("strMsg ={}, orderId={}", strMsg, orderId);

			if(StringHelper.isNotEmpty( strMsg)){
				logger.info("will delete strMsg, orderId={}", orderId);
				RedisCilent.delListVal(HC_ORDER_LIST, 1 , strMsg);
			}
		}
	}

	public OrderStrMsg updOrderStrMsg(OrderStrMsg orderStrMsg) {
		Long userId = null;
		Long productId = null;

		if (StringHelper.isNotEmpty(orderStrMsg.getUserId())) {
			userId = Long.valueOf(orderStrMsg.getUserId());
		}

		if (StringHelper.isNotEmpty(orderStrMsg.getProductId())) {
			productId = Long.valueOf(orderStrMsg.getProductId());
		}

		// 如果用户或产品不存在，则返回空
		if (userId == null || productId == null) {
			return null;
		}

		// 01加入顾客 及所属理财师基本属性
		SysUser user = userService.findById(userId);
		if (user != null) {
			orderStrMsg.setUserId(user.getId().toString());
			orderStrMsg.setUserName(user.getRealName());
			orderStrMsg.setUserPhoneNum(user.getName());
		}

		// 理财师信息
		if (StringHelper.isNotEmpty(orderStrMsg.getFinancialPlannerId())) {
			Long finUserId = Long.valueOf(orderStrMsg.getFinancialPlannerId());
			SysUser financialPlanner = userService.findById(finUserId);
			if (financialPlanner != null) {
				orderStrMsg.setFinancialPlannerId(financialPlanner.getId()
						.toString());
				orderStrMsg.setFinancialPlannerName(financialPlanner
						.getRealName());
				orderStrMsg.setFinancialPlannerPhoneNum(financialPlanner
						.getName());

				if (financialPlanner.getOrgId() != null) {

					Organization org = orgService.findById(financialPlanner
							.getOrgId());
					if (org != null) {
						orderStrMsg.setFinancialPlannerDepName(org.getFlag02());
					}

				}
			}
		}

		// 02 加入产品信息
		ProductInfo productInfo = productService.findById(productId);
		if (productInfo != null) {
			orderStrMsg.setProductId(productInfo.getId().toString());
			orderStrMsg.setProductName(productInfo.getName());

			orderStrMsg.setProductTerm(productInfo.getProTermStr());
			orderStrMsg.setProductCode(productInfo.getProNo());
			orderStrMsg.setProductTopType(productInfo.getProdTopType()
					.toString());
			Company company = comService.findById(productInfo.getIssuerId());
			if (company != null) {
				orderStrMsg.setProductCompanyId(company.getId().toString());
				orderStrMsg.setProductCompanyName(company.getName());
			}
		}

		// 03 加入支付信息
		String paymentIdStr = orderStrMsg.getPaymentId();
		
		//logger.info("paymentIdStr = {}" + paymentIdStr);
		
		Long paymentId = null;
		if (StringHelper.isNotEmpty(paymentIdStr)) {
			paymentId = Long.valueOf(paymentIdStr);
		}

		//logger.info("paymentId = {}" + paymentId);
		
		if (paymentId != null) {
			Payment payment = null;
			if (paymentService.existById(paymentId)) {
				payment = paymentService.findById(paymentId);
			} else if (11111111L == paymentId) {// 富友金账户
				HqlFilter filter = new HqlFilter();
				filter.addEQFilter("userId", userId);
				filter.addEQFilter("cardStatus",
						CardStatusCode.PAYMENT_DISPLAY_SHOW);
				filter.addSql(" and supportCompany like '1%' ");
				List<Payment> paymentList = paymentService.findByFilter(filter);
				if (paymentList != null && paymentList.size() > 0) {
					payment = paymentList.get(0);

				}
			}
			if (payment != null) {
				orderStrMsg.setPaymentId("" + paymentId);
				orderStrMsg.setPaymentBankCardNo(payment.getPaymentNo());
				orderStrMsg.setPaymentBankName(payment.getBankName());
				orderStrMsg.setIdentity(payment.getIdentityNo());
				orderStrMsg.setPaymentUserName(payment.getAccountName());
			}
		}

		return orderStrMsg;
	}

	/**
	 * 更新到期订单的支付状态为已汇款， 只要是火柴订单（companyId = 3），支付状态为已支付（payStatus = 2）,
	 * 并且当日前到期（dividendDate < maxTimeLong）, 则更改支付状态为已回款
	 * 
	 * maxTimeLong 为当日 最大时间
	 */
	public void updPayBackOrder() {
		HqlFilter hqlfilter = new HqlFilter();
		hqlfilter.addEQFilter("payStatus", ConstantOrderStatus.PAY_STATUS_TRUE);

		// 当时最大时间
		Long maxTimeLong = DateUtil.endOfTodDay();
		hqlfilter.addSql("  and paymentId <> 11111111 and dividendDate <  "
				+ maxTimeLong);

		List<OrderInfo> orderList = orderService.findByFilter(hqlfilter);

		logger.info(" updPayBackOrder get order filter = "
				+ hqlfilter.getWhereAndOrderHql());
		for (OrderInfo orderInfo : orderList) {

			/*
			if (orderInfo.getCompanyId() == 3 && orderInfo.getPayStatus() == 2) {
				logger.info(" order will update status = 4, 即已回款。 orderId = "
						+ orderInfo.getId());
				orderInfo.setPayStatus(ConstantOrderStatus.PAY_STATUS_PAYBACK);
				orderInfo
						.setConfirmStatus(ConstantOrderStatus.CONFIRM_STATUS__PAYBACK);
				orderService.update(orderInfo);
			}
			*/
			if	 (orderInfo.getPayStatus() == 2 ) {
				logger.info(" order will update status = 4, 即已回款。 orderId = "
						+ orderInfo.getId());
				orderInfo.setPayStatus(ConstantOrderStatus.PAY_STATUS_PAYBACK);
				orderInfo
						.setConfirmStatus(ConstantOrderStatus.CONFIRM_STATUS__PAYBACK);
				orderService.update(orderInfo);
			}


		}
	}

	/**
	 * 获取加息之后的产品id,
	 * 
	 * @return
	 */
	public Long getNewProductId(Long productId, BigDecimal rate) {
		Long newProdId = null;

		ProductInfo oldProduct = productService.findById(productId);

		if (oldProduct == null || rate == null) {
			return null;
		}
		
		if(rate.compareTo(BigDecimal.valueOf(0.0050)) == 0){
			newProdId = oldProduct.addRateProduct01;
		}else if(rate.compareTo(BigDecimal.valueOf(0.0020)) == 0){
			newProdId = oldProduct.addRateProduct02;
		}

		if(newProdId != null) {
			logger.info("**********create hcorder with userCard rate={}, productId={}, new ProductID={}", rate, productId, newProdId);
		}
		return newProdId;
	}

}
